package com.yeqf.expandrecyclerview.Adapter

import android.content.Context
import android.support.v7.widget.RecyclerView
import android.util.SparseArray
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView

/**
 * Created by iPanel on 2017/7/11.
 */
abstract class RecyclerAdapter<T>(private val context: Context) : RecyclerView.Adapter<RecyclerAdapter.ViewHolder>() {

    companion object {
        private val TYPE_HEADER = -1
        private val TYPE_ITEM = 0
        private val TYPE_FOOTER = 1
    }

    private var mDatas: ArrayList<T>? = null
    var listener: OnClickListener? = null
    var hasHeader = false
    var hasFooter = false
    var itemLayoutId: Int = 0
    var headerLayoutId: Int = 0
    var footerLayoutId: Int = 0
    var clickViewId: Int = 0

    fun setItemLayout(layoutId: Int): RecyclerAdapter<T> {
        itemLayoutId = layoutId
        return this
    }

    fun setHeaderLayout(layoutId: Int): RecyclerAdapter<T> {
        hasHeader = true
        headerLayoutId = layoutId
        return this
    }

    fun setFooterLayout(layoutId: Int): RecyclerAdapter<T> {
        hasFooter = true
        footerLayoutId = layoutId
        return this
    }

    fun setItemClickView(viewId: Int, listener: OnClickListener): RecyclerAdapter<T> {
        clickViewId = viewId
        this.listener = listener
        return this
    }

    fun setItems(mDatas: ArrayList<T>) {
        this.mDatas = mDatas
        notifyDataSetChanged()
    }

    override fun getItemViewType(position: Int): Int {
        if (hasHeader && position == 0)
            return TYPE_HEADER
        else if (hasFooter && position == itemCount - 1)
            return TYPE_FOOTER
        else
            return TYPE_ITEM
    }

    override fun getItemCount(): Int {
        var count = mDatas?.size ?: 0
        if (hasHeader)
            count++
        if (hasFooter)
            count++
        return count
    }

    override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder? {
        var holder: ViewHolder? = null
        when (viewType) {
            TYPE_HEADER -> {
                holder = ViewHolder.get(context, parent, headerLayoutId)
            }
            TYPE_ITEM -> {
                holder = ViewHolder.get(context, parent, itemLayoutId)
            }
            TYPE_FOOTER -> {
                holder = ViewHolder.get(context, parent, footerLayoutId)
            }
        }
        return holder
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        if (hasHeader && position == 0) {
            onBindHeaderDatas(holder)
        } else if (hasFooter && position == itemCount - 1) {
            onBindFooterDatas(holder)
        } else {
            onItemClickEvent(holder, position)
            if (!hasHeader)
                onBindItemDatas(holder, mDatas?.get(position), position)
            else
                onBindItemDatas(holder, mDatas?.get(position - 1), position - 1)
        }
    }

    fun onItemClickEvent(holder: ViewHolder, position: Int) {
        if(listener != null) {
            val v: View? = holder.getView<View>(clickViewId)
            if (v != null) {
                v.isClickable = true
                v.setOnClickListener { listener?.onItemClick(v, position) }
                v.setOnLongClickListener { listener?.onItemLongClick(v, position) ?: false }
            } else {
                throw RuntimeException("Invalid view id")
            }
        }
    }

    /**
     * 绑定item数据
     */
    abstract fun onBindItemDatas(holder: ViewHolder, data: T?, position: Int)

    /**
     * 处理header数据
     */
    open fun onBindHeaderDatas(holder: ViewHolder) {
        if (hasHeader)
            throw RuntimeException("Please override the method onBindHeaderDatas()")
    }

    /**
     * 处理footer数据
     */
    open fun onBindFooterDatas(holder: ViewHolder) {
        if (hasFooter)
            throw RuntimeException("Please override the method onBindFooterDatas()")
    }

    class ViewHolder(val context: Context, var view: View) : RecyclerView.ViewHolder(view) {
        companion object {
            fun get(context: Context, parent: ViewGroup?, layoutId: Int) : ViewHolder {
                val v: View = LayoutInflater.from(context).inflate(layoutId, parent, false)
                return ViewHolder(context, v)
            }
        }
        private val mViews: SparseArray<View> = SparseArray<View>()

        fun <E : View> getView(viewId: Int): E? {
            var v: View? = mViews.get(viewId)
            if(v == null) {
                v = view.findViewById(viewId)
                mViews.put(viewId, v)
            }
            return v as E?
        }
    }
}

interface OnClickListener {
    fun onItemClick(v: View, position: Int)
    fun onItemLongClick(v: View, position: Int): Boolean
}